package com.miniapp.config;

import com.miniapp.filter.ApiAccessLogFilter;
import com.miniapp.filter.ContentCachingFilter;
import com.miniapp.interceptor.ApiAccessLogInterceptor;
import com.miniapp.interceptor.AuthInterceptor;
import com.miniapp.interceptor.SqlInjectionInterceptor;
import com.miniapp.service.ApiAccessLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.servlet.Filter;

/**
 * Web配置类
 * @author author
 * @date 2025-09-01 10:31
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private AuthInterceptor authInterceptor;

    @Autowired
    private ApiAccessLogInterceptor apiAccessLogInterceptor;

    /**
     * 注册SQL注入拦截器
     */
    @Bean
    public SqlInjectionInterceptor sqlInjectionInterceptor() {
        return new SqlInjectionInterceptor();
    }

    /**
     * 注册内容缓存过滤器，用于获取请求体
     */
    @Bean
    public ContentCachingFilter contentCachingFilter() {
        return new ContentCachingFilter();
    }

    /**
     * 创建 ApiAccessLogFilter Bean，记录 API 请求日志
     */
    @Bean
    @ConditionalOnProperty(prefix = "access-log", value = "enable", matchIfMissing = true) // 允许使用 access-log.enable=false 禁用访问日志
    public FilterRegistrationBean<ApiAccessLogFilter> apiAccessLogFilter(@Value("${spring.application.name}") String applicationName,
                                                                         ApiAccessLogService accessLogService) {
        ApiAccessLogFilter filter = new ApiAccessLogFilter(applicationName, accessLogService);
        return createFilterBean(filter, -103);
    }

    private static <T extends Filter> FilterRegistrationBean<T> createFilterBean(T filter, Integer order) {
        FilterRegistrationBean<T> bean = new FilterRegistrationBean<>(filter);
        bean.setOrder(order);
        return bean;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(sqlInjectionInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/error", "/static/**");

        registry.addInterceptor(authInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns("/error", "/static/**");

        registry.addInterceptor(apiAccessLogInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns("/error", "/static/**");
    }
}
